package hc.j2me;

import hc.core.ClientInitor;
import hc.core.ContextManager;
import hc.core.EventCenter;
import hc.core.HCTimer;
import hc.core.IContext;
import hc.core.IEventHCListener;
import hc.core.IScreen;
import hc.core.Message;
import hc.core.MsgBuilder;
import hc.core.ReceiveServer;
import hc.core.RootServerConnector;
import hc.core.data.DataServerConfig;
import hc.core.data.ServerConfig;
import hc.core.sip.SIPManager;
import hc.core.util.IHCURLAction;
import hc.core.util.LogManager;
import hc.j2me.ui.UIManager;
import hc.j2me.util.Jcip;
import hc.j2me.util.ScreenUtil;
import hc.j2me.util.SoundUtil;

import java.io.ByteArrayInputStream;

import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Form;

public class J2MEContext extends IContext {

	public final Object getSysImg() {
		return Jcip.SYSTEM_IMAGE;
	}

	public final boolean isSoundOnMode() {
		return (Starter.config.isMute == false);
	}

	public J2MEContext() {
		SIPManager.setSIPContext(new J2MESIPContext());
		super.init(new ReceiveServer(), new J2MEUDPReceiveServer());
	}

	public final void displayMessage(String caption, String text, int type,
			Object imageData, int timeOut) {
		Starter.displayAlert(caption, text, type, imageData, timeOut);
	}

	public void exit() {
		Main.notifyExit();
	}

	public final void notifyShutdown() {
		// hc.core.L.V=hc.core.L.O?false:LogManager.log("Client notify shutdown");

		if (ContextManager.cmStatus == ContextManager.STATUS_CLIENT_SELF) {
			// L.V = L.O ? false :
			// LogManager.log("send out E_TAG_SHUT_DOWN_BETWEEN_CS");
			// 向服务器发送一个下线通知
			send(MsgBuilder.E_TAG_SHUT_DOWN_BETWEEN_CS,
					RootServerConnector.getHideToken());
		}

		RootServerConnector
				.notifyLineOffType(RootServerConnector.LOFF_MobReqExit_STR);

		try {
			shutDown();
		} catch (Exception e) {
			// 有可能服务器先断线后，导致状态变量，产生异常，所以增加调用后方法
			exit();
		}
	}

	public void run() {
		ClientInitor.doNothing();

		EventCenter.addListener(new IEventHCListener(){
			public boolean action(final byte[] bs) {
				DataServerConfig dsc = new DataServerConfig();
				dsc.setBytes(bs);
				ServerConfig sc = ServerConfig.getInstance();
				if(sc == null){
					sc = new ServerConfig();
					ServerConfig.setInstance(sc);
				}
				sc.readFrom(dsc);
				
				LogManager.info("Received SC");
				
				//发送客户机信息
				ScreenClientManager.sendClientInfo();
				
				return true;
			}

			public byte getEventTag() {
				return MsgBuilder.E_TRANS_SERVER_CONFIG;
			}});
		

		EventCenter.addListener(new IEventHCListener() {
			public boolean action(final byte[] bs) {
				String str = Message.getMsgBody(bs, MsgBuilder.INDEX_MSG_DATA);
				// hc.core.L.V=hc.core.L.O?false:LogManager.log("Refresh:" +
				// str);
				Jcip jcip = new Jcip(str);
				String formID = jcip.getString();

				Object d = UIManager.getCurrDisplayable();

				if (d instanceof hc.j2me.item.Form) {
					hc.j2me.item.Form form = (hc.j2me.item.Form) d;
					if (form.getScreenID().equals(formID)) {
						// hc.core.L.V=hc.core.L.O?false:LogManager.log("Update Form:"
						// + formID);
						form.update(jcip);
					}else{
						IScreen screen = UIManager.getDisplayableByName(formID);
						if(screen != null && screen instanceof hc.j2me.item.Form){
							((hc.j2me.item.Form)screen).update(jcip);
						}
					}
				}
				return true;
			}

			public byte getEventTag() {
				return MsgBuilder.E_JCIP_FORM_REFRESH;
			}
		});

		EventCenter.addListener(new IEventHCListener() {
			boolean isShutdown = false;

			public byte getEventTag() {
				return MsgBuilder.E_TAG_SHUT_DOWN_BETWEEN_CS;
			}

			public boolean action(final byte[] bs) {
				if (isShutdown == false) {
					String serverToken = Message.getMsgBody(bs,
							MsgBuilder.INDEX_MSG_DATA);
					if (RootServerConnector.getHideToken().equals(serverToken)) {
						isShutdown = true;
						displayMessage(Starter.getUIString(ScreenUtil.INFO),
								Starter.getUIString("m01"), IContext.ERROR,
								null, 0);

						// 关闭exit，因为提示需要用户较长的阅读时间，并由用户来自行退出
						// exit();
					}
				}
				return true;
			}
		});

		EventCenter.addListener(new IEventHCListener() {
			public byte getEventTag() {
				return MsgBuilder.E_LINE_OFF_EXCEPTION;
			}

			public boolean action(final byte[] bs) {
				// if(Starter.isErrCertOnPwdOrCert == false){
				// L.V = L.O ? false :
				// LogManager.log("Connection fail, restart");
				ContextManager.setStatus(ContextManager.STATUS_EXIT);

				Form opForm = new Form(Starter.getUIString(ScreenUtil.ERROR));
				opForm.append(Starter.getUIString("1000")
						+ "\n\n"
						+ Starter.getUIString("m06")
						+ "\n"
						+ "1. "
						+ Starter.getUIString("m03")
						+ " : [☆☆☆☆☆ -> ☆]\n"
						+ "2. "
						+ Starter.getUIString("m05")
						+ " : [1000 -> 3000]\n"
						+ "3. "
						+ Starter.getUIString("m14")
						+ " : [Yes -> No]"
						+ "\n\n"
						+ "Please refer to the above recommendations, as appropriate, configure me.");
				opForm.setCommandListener(Starter.getOK_NOBIZ_LISTENER());
				opForm.addCommand(Starter.cmd_ok);

				UIManager.pushInAndSwithToNew(opForm);
				AlertType.ERROR.playSound(UIManager.UI_DISPLAY);

				// 使用手工退出
				// try{
				// Thread.sleep(5000);
				// }catch (Exception e) {
				//
				// }
				//
				// if(Message.getMsgBody(bs,
				// MsgBuilder.INDEX_MSG_DATA).equals("true")){
				// notifyShutdown();
				// }else{
				// shutDown();
				// }
				// }
				return true;
			}
		});

		// 注意：SendServer应最先启动，ReceiverServer应最后启动，与流执行的次序相反。
		startAllServers();

	}

	// public static void buildSimuClient(){
	// ContextManager.setSimulate(true);
	//
	// J2MEContext se = (J2MEContext)ContextManager.getContextInstance();
	//
	// J2MESendServer s = (J2MESendServer)se.getSendServer();
	// // String ua = "datagram://127.0.0.1:9234";
	// String clientAdd = "datagram://:9235";
	//
	// ContextManager.getContextInstance().setTargetPeer("127.0.0.1", "9234",
	// null);
	// // setUDPTargetAddress(ua);
	// UDPDatagramConnection udpServerSocket = null;
	// try {
	// udpServerSocket = (UDPDatagramConnection)Connector.open(clientAdd);
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// s.setUdpServerSocket(udpServerSocket);
	//
	// //做一个仿真的。
	// J2MEReceiveServer r = (J2MEReceiveServer)se.getReceiveServer();
	// // DatagramSocket receiveServerSocket = null;
	// // try {
	// // receiveServerSocket = new DatagramSocket(1236, ia);
	// // } catch (SocketException e) {
	// // e.printStackTrace();
	// // }
	// try {
	// r.setUdpServerSocket(udpServerSocket);
	// //
	// r.setUdpServerSocket((UDPDatagramConnection)Connector.open(clientAdd));
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	//
	// ContextManager.setStatus(ContextManager.STATUS_CLIENT_SELF);
	// }

	// public final byte[] getDatagramBytes(Object dp) {
	// return ((Datagram)dp).getData();
	// }
	//
	// public void setDatagramBytes(Object dp, byte[] bs) {
	// ((Datagram)dp).setData(bs, 0, bs.length);
	// }

	// private final Message msg = new Message();

	// j2me cldc 1.0 cant exec Thread.interrupt
	public final void interrupt(Thread thread) {
	}

	// public final void setTargetPeer(String ip, String port, Object dp) throws
	// Exception {
	// String ipPort = "datagram://" + ip + ":" + port;
	// if(dp == null){
	// // String ua = "datagram://127.0.0.1:9234";
	// hc.core.L.V=hc.core.L.O?false:LogManager.log("setTargetPeer, IP:" +
	// ipPort);
	//
	// SocketConnection socket =
	// (SocketConnection)SIPManager.getSIPContext().buildSocket(0, ip,
	// Integer.parseInt(port));
	// if(socket != null){
	// SIPManager.getSIPContext().deploySocket(socket, socket.openInputStream(),
	// socket.openOutputStream());
	// }else{
	//
	// }
	// // udpAddress = ipPort;
	// }else{
	// try {
	// ((Datagram)dp).setAddress(ipPort);
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	// }
	// }

	public Object doExtBiz(short bizNo, Object newParam) {
		if (bizNo == IContext.BIZ_UPLOAD_LINE_ON) {
			return null;
		} else if (bizNo == IContext.BIZ_SERVER_AFTER_CERTKEY_ERROR) {
			LogManager.info("Curr certification is invalid");
			LogManager
					.info("Certification of Server is newer and DISABLE transmit to me.");
			LogManager
					.info("Please keep 'Transmit Certification : on' at HomeCenter App Server");
			LogManager.info("Press any key to exit!");

			ContextManager.getContextInstance().displayMessage(
					Starter.getUIString(ScreenUtil.ERROR),
					Starter.getUIString("1023"), IContext.ERROR, null, 0);
		} else if (bizNo == IContext.BIZ_SERVER_AFTER_PWD_ERROR) {
			LogManager.info("Receive error password status");
			LogManager
					.info("Please\n"
							+ "1. recheck it\n"
							+ "2. some charset is not support by mobile, change password of HomeCenter.");
			LogManager.info("Press any key to exit!");

			ContextManager.getContextInstance().displayMessage(
					Starter.getUIString(ScreenUtil.ERROR),
					Starter.getUIString("1019"), IContext.ERROR, null, 0);
		} else if (bizNo == IContext.BIZ_SERVER_AFTER_SERVICE_IS_FULL) {
			LogManager.info("Receive service is full status");

			ContextManager.getContextInstance().displayMessage(
					Starter.getUIString(ScreenUtil.ERROR),
					Starter.getUIString("m08"), IContext.ERROR, null, 0);
		} else if (bizNo == IContext.BIZ_SERVER_AFTER_UNKNOW_STATUS) {
			LogManager.info("Receive unknown server status");

			ContextManager.getContextInstance().displayMessage(
					Starter.getUIString(ScreenUtil.ERROR),
					Starter.getUIString("1024"), IContext.ERROR, null, 0);
		} else if (bizNo == IContext.BIZ_SERVER_AFTER_OLD_MOBI_VER_STATUS) {
			LogManager.info(Starter.getUIString("1031"));
			LogManager.info("Press any key to exit!");

			ContextManager.getContextInstance().displayMessage(
					Starter.getUIString(ScreenUtil.ERROR),
					Starter.getUIString("1031"), IContext.ERROR, null, 0);
		} else if (bizNo == IContext.BIZ_LOAD_SERVER_CONFIG) {
			// 本方法仅用于服务器
			return null;
		} else if (bizNo == IContext.BIZ_NEW_NOTIFICATION) {
			if (newParam.equals("on")) {
				soundNotify();
			} else {
				readedAllNotify();
			}
		} else if (bizNo == IContext.BIZ_VERSION_MID_OR_PC) {
			return Main.getMidletVer();
		} else if (bizNo == IContext.BIZ_PLAYSOUND) {
			byte[] soundBS = (byte[]) newParam;
			ByteArrayInputStream ais = new ByteArrayInputStream(soundBS, 0,
					soundBS.length);
			SoundUtil.playAU(ais);
			return null;
		} else if (bizNo == IContext.BIZ_SERVER_LINEOFF) {
			Starter.isServerLineOff = true;
		}
		return null;
	}

	private static boolean isDispedMsg = false;

	private static HCTimer notifySoundTimer = new HCTimer("", 10000, false) {
		public void doBiz() {
			UIManager.vibrate(250);
			
//			某些机器会产生震动，测试环境下，产生短音
//			AlertType.ALARM.playSound(UIManager.UI_DISPLAY);
			
			SoundUtil.playTone(100, 400, 75);

			// 有可能首次显示，所以要置于声音和震动之后
			// if(isDispedMsg == false){
			// ContextManager.getContextInstance().displayMessage(
			// Starter.getUIString(ScreenUtil.INFO),
			// Starter.getUIString("1027"), IContext.INFO, null, 0);
			// isDispedMsg = true;
			// }
		}
	};

	/**
	 * TODO 消息列表，增加调用本逻辑
	 */
	private static void readedAllNotify() {
		isDispedMsg = false;
		notifySoundTimer.setEnable(false);
	}

	private static void soundNotify() {
		if (notifySoundTimer.isEnable() == false) {
			notifySoundTimer.setEnable(true);
			notifySoundTimer.doNowAsynchronous();
		}
	}

	public Object getProperty(Object propertyID) {
		if (Starter.properties == null) {
			return null;
		} else {
			return Starter.properties.get(propertyID);
		}
	}

	// public void copyDatagramAddress(Object from, Object to) {
	// Datagram dpTo = (Datagram)to;
	// Datagram dpFrom = (Datagram)from;
	//
	// dpTo.setAddress(dpFrom);
	// }

	IHCURLAction urlAction = new J2MEURLAction();

	public IHCURLAction getHCURLAction() {
		return urlAction;
	}

}
